import type { Component, VNodeProps } from 'vue';

type ColSpanType = number | string;
export interface ColEx {
  style?: any;
  /**
   * raster number of cells to occupy, 0 corresponds to display: none
   * @default none (0)
   * @type ColSpanType
   */
  span?: ColSpanType;

  /**
   * raster order, used in flex layout mode
   * @default 0
   * @type ColSpanType
   */
  order?: ColSpanType;

  /**
   * the layout fill of flex
   * @default none
   * @type ColSpanType
   */
  flex?: ColSpanType;

  /**
   * the number of cells to offset Col from the left
   * @default 0
   * @type ColSpanType
   */
  offset?: ColSpanType;

  /**
   * the number of cells that raster is moved to the right
   * @default 0
   * @type ColSpanType
   */
  push?: ColSpanType;

  /**
   * the number of cells that raster is moved to the left
   * @default 0
   * @type ColSpanType
   */
  pull?: ColSpanType;

  /**
   * <576px and also default setting, could be a span value or an object containing above props
   * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
   */
  xs?: { span: ColSpanType; offset: ColSpanType } | ColSpanType;

  /**
   * ≥576px, could be a span value or an object containing above props
   * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
   */
  sm?: { span: ColSpanType; offset: ColSpanType } | ColSpanType;

  /**
   * ≥768px, could be a span value or an object containing above props
   * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
   */
  md?: { span: ColSpanType; offset: ColSpanType } | ColSpanType;

  /**
   * ≥992px, could be a span value or an object containing above props
   * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
   */
  lg?: { span: ColSpanType; offset: ColSpanType } | ColSpanType;

  /**
   * ≥1200px, could be a span value or an object containing above props
   * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
   */
  xl?: { span: ColSpanType; offset: ColSpanType } | ColSpanType;

  /**
   * ≥1600px, could be a span value or an object containing above props
   * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
   */
  xxl?: { span: ColSpanType; offset: ColSpanType } | ColSpanType;
}

type AntdComponentType =
  | 'AAffix'
  | 'AAlert'
  | 'AAnchor'
  | 'AAnchorLink'
  | 'AAutoComplete'
  | 'OptGroup2'
  | 'Option2'
  | 'AAvatar'
  | 'AAvatarGroup'
  | 'ABackTop'
  | 'ABadge'
  | 'ABadgeRibbon'
  | 'ABreadcrumb'
  | 'ABreadcrumbItem'
  | 'ABreadcrumbSeparator'
  | 'AButton'
  | 'AButtonGroup'
  | 'ACalendar'
  | 'ACard'
  | 'ACardGrid'
  | 'ACardMeta'
  | 'ACarousel'
  | 'ACascader'
  | 'ACheckableTag'
  | 'ACheckbox'
  | 'ACheckboxGroup'
  | 'ACol'
  | 'ACollapse'
  | 'ACollapsePanel'
  | 'AComment'
  | 'AConfigProvider'
  | 'ADatePicker'
  | 'ADescriptions'
  | 'ADescriptionsItem'
  | 'ADirectoryTree'
  | 'ADivider'
  | 'ADrawer'
  | 'ADropdown'
  | 'ADropdownButton'
  | 'AEmpty'
  | 'AFloatButton'
  | 'AFloatButtonGroup'
  | 'AForm'
  | 'AFormItem'
  | 'AFormItemRest'
  | 'AImage'
  | 'AImagePreviewGroup'
  | 'AInput'
  | 'AInputGroup'
  | 'AInputNumber'
  | 'AInputPassword'
  | 'AInputSearch'
  | 'ALayout'
  | 'ALayoutContent'
  | 'ALayoutFooter'
  | 'ALayoutHeader'
  | 'ALayoutSider'
  | 'AList'
  | 'AListItem'
  | 'AListItemMeta'
  | 'ALocaleProvider'
  | 'AMentions'
  | 'AMentionsOption'
  | 'AMenu'
  | 'AMenuDivider'
  | 'AMenuItem'
  | 'AMenuItemGroup'
  | 'AModal'
  | 'AMonthPicker'
  | 'APageHeader'
  | 'APagination'
  | 'APopconfirm'
  | 'APopover'
  | 'AProgress'
  | 'AQRCode'
  | 'AQuarterPicker'
  | 'ARadio'
  | 'ARadioButton'
  | 'ARadioGroup'
  | 'ARangePicker'
  | 'ARate'
  | 'AResult'
  | 'ARow'
  | 'ASegmented'
  | 'ASelect'
  | 'OptGroup'
  | 'Option'
  | 'ASkeleton'
  | 'ASkeletonAvatar'
  | 'ASkeletonButton'
  | 'ASkeletonImage'
  | 'ASkeletonInput'
  | 'SkeletonTitle'
  | 'ASlider'
  | 'ASpace'
  | 'ASpin'
  | 'AStatistic'
  | 'AStatisticCountdown'
  | 'AStep'
  | 'ASteps'
  | 'ASubMenu'
  | 'ASwitch'
  | 'ATabPane'
  | 'ATable'
  | 'ATableColumn'
  | 'ATableColumnGroup'
  | 'ATableSummary'
  | 'ATableSummaryCell'
  | 'ATableSummaryRow'
  | 'ATabs'
  | 'ATag'
  | 'ATextarea'
  | 'ATimePicker'
  | 'ATimeRangePicker'
  | 'ATimeline'
  | 'ATimelineItem'
  | 'ATooltip'
  | 'ATour'
  | 'ATransfer'
  | 'ATree'
  | 'ATreeNode'
  | 'ATreeSelect'
  | 'TreeNode2'
  | 'ATypography'
  | 'Link'
  | 'Paragraph'
  | 'Text2'
  | 'Title'
  | 'AUpload'
  | 'AUploadDragger'
  | 'AWatermark'
  | 'AWeekPicker';

export type ComponentTypes =
  | 'InputCountDown'
  | 'ApiSelect'
  | 'ApiTree'
  | 'ApiTreeSelect'
  | 'ApiRadioGroup'
  | 'ApiCascader'
  | 'Uploader'
  | 'ApiTransfer'
  | 'RadioButtonGroup'
  | 'Upload'
  | 'ImageUpload'
  | 'IconPicker'
  | 'CropperAvatar'
  | 'BasicTitle'
  | AntdComponentType;
export type ComponentType = ComponentTypes & keyof ComponentProps;

type MethodsNameToCamelCase<
  T extends string,
  M extends string = '',
> = T extends `${infer F}-${infer N}${infer Tail}`
  ? MethodsNameToCamelCase<Tail, `${M}${F}${Uppercase<N>}`>
  : `${M}${T}`;

type MethodsNameTransform<T> = {
  [K in keyof T as K extends `on${string}` ? MethodsNameToCamelCase<K> : never]: T[K];
};

type ExtractPropTypes<T extends Component> = T extends new (...args: any) => any
  ? Omit<InstanceType<T>['$props'], keyof VNodeProps>
  : never;

interface _CustomComponents {
  ApiSelect: ExtractPropTypes<(typeof import('../components/ApiSelect.vue'))['default']>;
  ApiTree: ExtractPropTypes<(typeof import('../components/ApiTree.vue'))['default']>;
  ApiTreeSelect: ExtractPropTypes<(typeof import('../components/ApiTreeSelect.vue'))['default']>;
  ApiRadioGroup: ExtractPropTypes<(typeof import('../components/ApiRadioGroup.vue'))['default']>;
  RadioButtonGroup: ExtractPropTypes<
    (typeof import('../components/RadioButtonGroup.vue'))['default']
  >;
  ApiCascader: ExtractPropTypes<(typeof import('../components/ApiCascader.vue'))['default']>;

  Upload: ExtractPropTypes<(typeof import('@/components/Upload/src/BasicUpload.vue'))['default']>;
  ImageUpload: ExtractPropTypes<
    (typeof import('@/components/Upload/src/components/ImageUpload.vue'))['default']
  >;
  IconPicker: ExtractPropTypes<(typeof import('@/components/Icon/src/IconPicker.vue'))['default']>;
  ApiTransfer: ExtractPropTypes<(typeof import('../components/ApiTransfer.vue'))['default']>;
  CropperAvatar: ExtractPropTypes<
    (typeof import('@/components/Cropper/src/CropperAvatar.vue'))['default']
  >;
  BasicTitle: ExtractPropTypes<(typeof import('@/components/Basic/src/BasicTitle.vue'))['default']>;
  InputCountDown: ExtractPropTypes<
    (typeof import('@/components/CountDown/src/CountdownInput.vue'))['default']
  >;
}

type CustomComponents<T = _CustomComponents> = {
  [K in keyof T]: T[K] & MethodsNameTransform<T[K]>;
};

export interface ComponentProps {
  AInput: ExtractPropTypes<(typeof import('ant-design-vue/es/input'))['default']>;
  AInputGroup: ExtractPropTypes<(typeof import('ant-design-vue/es/input'))['InputGroup']>;
  AInputPassword: ExtractPropTypes<(typeof import('ant-design-vue/es/input'))['InputPassword']>;
  AInputSearch: ExtractPropTypes<(typeof import('ant-design-vue/es/input'))['InputSearch']>;
  AInputTextArea: ExtractPropTypes<(typeof import('ant-design-vue/es/input'))['Textarea']>;
  AInputNumber: ExtractPropTypes<(typeof import('ant-design-vue/es/input-number'))['default']>;
  InputCountDown: CustomComponents['InputCountDown'] & ComponentProps['AInput'];
  ASelect: ExtractPropTypes<(typeof import('ant-design-vue/es/select'))['default']>;
  ApiSelect: CustomComponents['ApiSelect'] & ComponentProps['ASelect'];
  ATreeSelect: ExtractPropTypes<(typeof import('ant-design-vue/es/tree-select'))['default']>;
  ApiTree: CustomComponents['ApiTree'] &
    ExtractPropTypes<(typeof import('ant-design-vue/es/tree'))['default']>;
  ApiTreeSelect: CustomComponents['ApiTreeSelect'] & ComponentProps['ATreeSelect'];
  ApiRadioGroup: CustomComponents['ApiRadioGroup'] & ComponentProps['ARadioGroup'];
  RadioButtonGroup: CustomComponents['RadioButtonGroup'] & ComponentProps['ARadioGroup'];
  ARadioGroup: ExtractPropTypes<(typeof import('ant-design-vue/es/radio'))['RadioGroup']>;
  ACheckbox: ExtractPropTypes<(typeof import('ant-design-vue/es/checkbox'))['default']>;
  ACheckboxGroup: ExtractPropTypes<(typeof import('ant-design-vue/es/checkbox'))['CheckboxGroup']>;
  AAutoComplete: ExtractPropTypes<(typeof import('ant-design-vue/es/auto-complete'))['default']>;
  ApiCascader: CustomComponents['ApiCascader'] & ComponentProps['ACascader'];
  ACascader: ExtractPropTypes<(typeof import('ant-design-vue/es/cascader'))['default']>;
  ADatePicker: ExtractPropTypes<(typeof import('ant-design-vue/es/date-picker'))['default']>;
  AMonthPicker: ExtractPropTypes<(typeof import('ant-design-vue/es/date-picker'))['MonthPicker']>;
  ARangePicker: ExtractPropTypes<(typeof import('ant-design-vue/es/date-picker'))['RangePicker']>;
  AWeekPicker: ExtractPropTypes<(typeof import('ant-design-vue/es/date-picker'))['WeekPicker']>;
  ATimePicker: ExtractPropTypes<(typeof import('ant-design-vue/es/time-picker'))['TimePicker']>;
  ATimeRangePicker: ExtractPropTypes<
    (typeof import('ant-design-vue/es/time-picker'))['TimeRangePicker']
  >;
  ASwitch: ExtractPropTypes<(typeof import('ant-design-vue/es/switch'))['default']>;
  Upload: CustomComponents['Upload'];
  ImageUpload: CustomComponents['ImageUpload'];
  IconPicker: CustomComponents['IconPicker'];
  Render: Record<string, any>;
  ASlider: ExtractPropTypes<(typeof import('ant-design-vue/es/slider'))['default']>;
  ARate: ExtractPropTypes<(typeof import('ant-design-vue/es/rate'))['default']>;
  ADivider: ExtractPropTypes<(typeof import('ant-design-vue/es/divider'))['default']>;
  ApiTransfer: CustomComponents['ApiTransfer'] & ComponentProps['ATransfer'];
  ATransfer: ExtractPropTypes<(typeof import('ant-design-vue/es/transfer'))['default']>;
  CropperAvatar: CustomComponents['CropperAvatar'];
  BasicTitle: CustomComponents['BasicTitle'];
}
